Compilation is a process in which source code (e.g., a software application expressed in a high level programming language (e.g., C, C++, Fortran, Java) is converted into machine code (e.g., an executable in binary). Compilation usually involves the optimization of code to make it shorter and more efficient to run on a processor by the time it is converted into machine code. In source code, functions are called with particular arguments, which can be either variable or constant. The value of constant arguments can have a disproportionate effect of the execution time of the function. For example, in cases where arguments determine control flow (i.e., when constant arguments greatly influence the sequence of the execution of instructions within a particular function), execution time may vary greatly depending on the value of the constant arguments. There are two ways of optimizing the code when a function is called with constant arguments. The first is known as “inlining” the function at call sites that contain constant arguments. The second way is known as “function specialization,” which involves creating a specialized version of the function that is optimized for a particular set of constant arguments and then rewriting the calls to use this version.
Both of these optimization approaches can improve performance, but can also lead to (sometimes substantial) code size increases, which can be a serious drawback in space-constrained embedded development environments. Consequently, compilers tend to not use function specialization at the “optimize-for-size” optimization level. That is, in embedded development environments, the benefits of function specialization are often not utilized due to the fact that it is highly undesirable to use such an optimization technique that could potentially increase the overall size of the optimized code. It would be desirable to be able to use the optimization provided by function specialization without disadvantageously increasing code size.